package ru.usu.gv.uicomponents;

import ru.usu.gv.core.GraphCanvas;
import ru.usu.gv.uicomponents.viewitems.IViewItem;

import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Geometry;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.media.j3d.TransformGroup;

/**
 @author: Sergey Pupyrev 
 Apr 2, 2006
 */

public abstract class UIElementBase<T extends IViewItem>
{
	private BranchGroup branchGroup;
	private TransformGroup transformGroup;
	private Appearance appearance;
	private Geometry geometry;
	private Material material;

	private BranchGroup labelBranch;

	public UIElementBase()
	{
		branchGroup = createBranchGroup();
		transformGroup = createTransformGroup(branchGroup);

		appearance = new Appearance();
		appearance.setCapability(Appearance.ALLOW_MATERIAL_WRITE);

		material = new Material();
		material.setLightingEnable(true);
		material.setCapability(Material.ALLOW_COMPONENT_WRITE);
		appearance.setMaterial(material);
	}

	protected BranchGroup createBranchGroup()
	{
		BranchGroup branchGroup = new BranchGroup();
		branchGroup.setCapability(BranchGroup.ALLOW_DETACH);
		branchGroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
		branchGroup.setBounds(GraphCanvas.getInstance().getBoundingSphere());
		return branchGroup;
	}

	protected TransformGroup createTransformGroup(BranchGroup branchGroup)
	{
		TransformGroup transformGroup = new TransformGroup();
		transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		transformGroup.setCapability(TransformGroup.ENABLE_PICK_REPORTING);
		transformGroup.setCapability(TransformGroup.ALLOW_LOCAL_TO_VWORLD_READ);
		transformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		transformGroup.setCapability(TransformGroup.ALLOW_CHILDREN_WRITE);
		transformGroup.setBounds(GraphCanvas.getInstance().getBoundingSphere());
		branchGroup.addChild(transformGroup);
		return transformGroup;
	}

	protected BranchGroup createLabelBranch(TransformGroup transformGroup)
	{
		BranchGroup labelBranch = new BranchGroup();
		labelBranch.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
		labelBranch.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);
		labelBranch.setBounds(GraphCanvas.getInstance().getBoundingSphere());
		transformGroup.addChild(labelBranch);
		return labelBranch;
	}

	protected void initBranchGroup()
	{
		GraphCanvas.getInstance().addChild(branchGroup);
	}

	protected TransformGroup getTransformGroup()
	{
		return transformGroup;
	}

	protected Appearance getAppearance()
	{
		return appearance;
	}

	protected Geometry getGeometry()
	{
		return geometry;
	}

	protected Material getMaterial()
	{
		return material;
	}

	protected void setBranchGroup(BranchGroup branchGroup)
	{
		this.branchGroup = branchGroup;
	}

	protected void setTransformGroup(TransformGroup transformGroup)
	{
		this.transformGroup = transformGroup;
	}

	protected void setGeometry(Geometry geometry)
	{
		this.geometry = geometry;
	}

	public void draw()
	{
		if (!branchGroup.isLive())
		{
			initBranchGroup();
		}
	}

	public abstract void highlight();

	public abstract void unhighlight();

	public abstract T getViewItem();

	public void delete()
	{
		branchGroup.detach();
	}

	public void makePickable(Shape3D shape)
	{
		UIUtilities.makePickable(this, shape);
	}

	protected BranchGroup getLabelBranch()
	{
		return labelBranch;
	}

	protected void setLabelBranch(BranchGroup labelBranch)
	{
		this.labelBranch = labelBranch;
		if (labelBranch != null)
			transformGroup.addChild(labelBranch);
	}

}
